﻿using System;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.Internal;
using Microsoft.EntityFrameworkCore.Utilities;
using Pomelo.EntityFrameworkCore.MyCat.ValueGeneration.Internal;

namespace Microsoft.EntityFrameworkCore.ValueGeneration.Internal
{
    public class MyCatValueGeneratorSelector : RelationalValueGeneratorSelector
    {
        private readonly IMycatSequenceValueGeneratorFactory _sequenceFactory;

        private readonly MyCatRelationalConnection _connection;
        public MyCatValueGeneratorSelector(
            [NotNull] ValueGeneratorSelectorDependencies cache,
              [NotNull] IMycatSequenceValueGeneratorFactory sequenceFactory,
            [NotNull] MyCatRelationalConnection connection
           )
            : base(cache)
        {
        }
        public new virtual IMycatValueGeneratorCache Cache => (IMycatValueGeneratorCache)base.Cache;


        public override ValueGenerator Select(IProperty property, IEntityType entityType)
        {
            Check.NotNull(property, nameof(property));
            Check.NotNull(entityType, nameof(entityType));

            return property.GetValueGeneratorFactory() == null
                   && property.MyCat().ValueGenerationStrategy == MyCatValueGenerationStrategy.SequenceHiLo
                ? _sequenceFactory.Create(property, Cache.GetOrAddSequenceState(property), _connection)
                : base.Select(property, entityType);
        }
        public override ValueGenerator Create(IProperty property, IEntityType entityType)
        {
            Check.NotNull(property, nameof(property));
            Check.NotNull(entityType, nameof(entityType));

            var ret = property.ClrType.UnwrapNullableType() == typeof(Guid)
                ? property.ValueGenerated == ValueGenerated.Never
                  || property.MyCat().DefaultValueSql != null
                    ? (ValueGenerator)new TemporaryGuidValueGenerator()
                    : new SequentialGuidValueGenerator()
                : base.Create(property, entityType);
            return ret;
        }
    }
}